// 创建画布
const canvas = wx.createCanvas()
const ctx = canvas.getContext('2d')

// 获取屏幕尺寸
const { windowWidth, windowHeight } = wx.getSystemInfoSync()
canvas.width = windowWidth
canvas.height = windowHeight

// 添加错误处理
wx.onError(function(res) {
  console.error('游戏出错:', res.message);
  // 尝试显示错误到屏幕上
  if (ctx) {
    ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = '#ff5555';
    ctx.font = '20px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('游戏加载出错，请重新启动', canvas.width / 2, canvas.height / 2);
    ctx.fillText(res.message.substring(0, 30), canvas.width / 2, canvas.height / 2 + 30);
  }
});

// 游戏配置
const config = {
  tileSize: 30, // 减小格子大小以适应更大的地图
  cols: Math.floor(windowWidth / 30),
  rows: Math.floor(windowHeight / 30),
  backgroundColor: '#88cc88', // 草地颜色
  pathColor: '#ccaa77',      // 路径颜色
  towerCost: {
    basic: 80,     // 降低塔的价格
    lightning: 130, // 闪电塔价格
    sniper: 120,
    splash: 160,
    slow: 100,
    shield: 150    // 护盾塔价格
  },
  towerHealth: {   // 塔的生命值
    basic: 100,
    lightning: 85,
    sniper: 80,
    splash: 90,
    slow: 85,
    shield: 120
  },
  // 每种塔的最大数量限制
  towerLimits: {
    basic: 10,
    lightning: 5,
    sniper: 5,
    splash: 5,
    slow: 5,
    shield: 3
  },
  // 建造相关配置 - 极简化版
  buildingSystem: {
    showGrid: true,      // 显示可建造网格
    requireNodes: false, // 不再需要在节点附近建造
    nodeRadius: 3,       // 保留作为参考
    gridColor: 'rgba(0, 255, 0, 0.4)',  // 更鲜明的可建造区域颜色
    nodeColor: '#FFD700', // 节点颜色
    highlightOnPlacement: true, // 放置模式下突出显示
    autoEnterBuildMode: true, // 自动进入建造模式
    mobileOptimized: true // 为移动设备优化
  },
  startGold: 1000   // 增加初始金币，方便建造
}

// 塔的类型定义
const TOWER_TYPES = {
  basic: {
    color: '#6666cc',
    range: 3,
    damage: 30,
    attackSpeed: 0.8,
    bulletColor: '#ffff00',
    bulletSize: 4,
    bulletSpeed: 8,
    hitEffect: true,
    attackType: 'normal'  // 普通攻击
  },
  lightning: {
    color: '#5533ff',
    range: 4,
    damage: 25,
    attackSpeed: 1.0,
    bulletColor: '#33ccff',
    bulletSize: 5,
    bulletSpeed: 10,
    hitEffect: true,
    chainCount: 3,        // 闪电链可攻击的敌人数量
    chainRange: 2,        // 闪电链跳跃范围
    chainDamageRate: 0.7, // 链式伤害衰减率
    attackType: 'chain'   // 闪电链攻击
  },
  sniper: {
    color: '#cc3333',
    range: 8,
    damage: 100,
    attackSpeed: 1.5,
    bulletColor: '#ff0000',
    bulletSize: 5,
    bulletSpeed: 12,
    criticalChance: 0.3,
    criticalMultiplier: 2.5,
    attackType: 'snipe'  // 狙击攻击
  },
  splash: {
    color: '#cc66cc',
    range: 3,
    damage: 25,
    attackSpeed: 1.2,
    bulletColor: '#ff66ff',
    bulletSize: 6,
    bulletSpeed: 6,
    splashRadius: 2,
    explosionSize: 30,
    attackType: 'splash'  // 溅射攻击
  },
  slow: {
    color: '#66cccc',
    range: 4,
    damage: 10,
    attackSpeed: 0.8,
    bulletColor: '#00ffff',
    bulletSize: 4,
    bulletSpeed: 7,
    slowEffect: 0.4,
    slowDuration: 3000,
    chainReaction: 2,
    attackType: 'slow'  // 减速攻击
  },
  shield: {
    color: '#4CAF50',  // 绿色
    range: 2,
    damage: 0,
    attackSpeed: 5,  // 每5秒激活一次护盾
    bulletColor: '#88ff88',
    bulletSize: 6,
    bulletSpeed: 4,
    shieldDuration: 3000,  // 护盾持续3秒
    shieldStrength: 0.5,   // 减少50%伤害
    attackType: 'shield'   // 护盾攻击
  }
}

// 敌人类型定义
const ENEMY_TYPES = {
  normal: {
    color: '#cc6666',
    health: 60,
    speed: 1.2,
    value: 60,
    size: 1.0,  // 增加尺寸
    imagePath: 'images/enemies/xiaoshe1.png',
    animationFrames: 4,
    animationSpeed: 10,
    deathEffect: true,
    attackDamage: 5,    // 普通攻击伤害
    attackSpeed: 1.0,   // 每秒攻击一次
    attackRange: 0.8    // 攻击范围（格子数）
  },
  fast: {
    color: '#66cc66',
    health: 40,
    speed: 2.5,
    value: 80,
    size: 0.9,  // 增加尺寸
    imagePath: 'images/enemies/xiaoshe1.png',
    animationFrames: 4,
    animationSpeed: 8,
    deathEffect: true,
    attackDamage: 3,    // 快速但伤害较低
    attackSpeed: 0.6,   // 攻击更频繁
    attackRange: 0.7    // 攻击范围较小
  },
  tank: {
    color: '#666666',
    health: 250,
    speed: 0.6,
    value: 150,
    size: 1.2,  // 增加尺寸
    armor: 0.2,
    imagePath: 'images/enemies/xiaoshe1.png',
    animationFrames: 4,
    animationSpeed: 15,
    deathEffect: true,
    attackDamage: 15,   // 高伤害
    attackSpeed: 2.0,   // 攻击较慢
    attackRange: 1.0,   // 攻击范围大
    canAttackMultiple: true  // 能同时攻击多个塔
  },
  boss: {
    color: '#cc3333',
    health: 1200,
    speed: 0.4,
    value: 600,
    size: 1.8,  // 增加尺寸
    armor: 0.3,
    imagePath: 'images/enemies/xiaoshe1.png',
    animationFrames: 4,
    animationSpeed: 20,
    deathEffect: true,
    minions: true,
    attackDamage: 30,     // 极高伤害
    attackSpeed: 3.0,     // 攻击非常慢
    attackRange: 1.5,     // 攻击范围很大
    canAttackMultiple: true, // 能同时攻击多个塔
    areaAttack: true      // 范围攻击
  },
  xiaoshe: {
    color: '#aa66cc',
    health: 150,
    speed: 1.5,
    value: 120,
    size: 1.1,  // 增加尺寸
    imagePath: 'images/enemies/xiaoshe1.png',
    animationFrames: 4,
    animationSpeed: 12,
    deathEffect: true,
    attackDamage: 8,      // 中等伤害
    attackSpeed: 1.2,     // 中等攻击速度
    attackRange: 0.9,     // 中等攻击范围
    canDisableShield: true // 可以暂时禁用护盾
  },
  huli: {
    color: '#ff9933',     // 橙色
    health: 300,          // 增加血量，之前是180
    speed: 1.8,
    value: 180,           // 增加奖励，因为更难击杀
    size: 1.5,            // 增加体积，之前是1.2
    imagePath: 'images/enemies/huli1.png',
    animationFrames: 2,   // 两帧动画
    animationSpeed: 18,   // 动画速度适中
    deathEffect: true,
    attackDamage: 12,     // 增加伤害，之前是10
    attackSpeed: 0.9,     // 较快攻击速度
    attackRange: 1.2,     // 较大攻击范围
    dodgeChance: 0.2      // 20%几率闪避攻击
  }
}

// 游戏状态
const gameState = {
  map: [],           // 地图数据
  towers: [],        // 防御塔数组
  enemies: [],       // 敌人数组
  bullets: [],       // 子弹数组
  gold: config.startGold,  // 金币数量
  wave: 1,          // 当前波数
  lives: 10,        // 生命值
  score: 0,         // 分数
  gameOver: false,   // 游戏是否结束
  selectedTowerType: 'basic',  // 当前选择的塔类型
  showIntro: true,   // 是否显示介绍界面
  activeShields: [], // 活跃的护盾效果列表
  buildNodes: [],    // 建造节点位置数组
  buildableGrid: [], // 可建造区域网格
  placementMode: false, // 是否处于放置模式
  lightningEffects: [], // 闪电链特效
  towerCounts: {     // 已建造的塔数量统计
    basic: 0,
    lightning: 0,
    sniper: 0,
    splash: 0,
    slow: 0,
    shield: 0
  },
  mouseX: undefined, // 鼠标/触摸X坐标
  mouseY: undefined  // 鼠标/触摸Y坐标
}

// 更大的路径点
const path = [
  {x: 0, y: 3},                          // 起点
  {x: Math.floor(config.cols * 0.2), y: 3},  // 向右
  {x: Math.floor(config.cols * 0.2), y: 8},  // 向下
  {x: Math.floor(config.cols * 0.6), y: 8},  // 向右
  {x: Math.floor(config.cols * 0.6), y: 3},  // 向上
  {x: Math.floor(config.cols * 0.8), y: 3},  // 向右
  {x: Math.floor(config.cols * 0.8), y: 12}, // 向下
  {x: Math.floor(config.cols * 0.4), y: 12}, // 向左
  {x: Math.floor(config.cols * 0.4), y: 15}, // 向下
  {x: Math.floor(config.cols - 2), y: 15},   // 向右
  {x: Math.floor(config.cols - 2), y: 8},    // 向上
  {x: Math.floor(config.cols * 0.8), y: 8},  // 向左
  {x: Math.floor(config.cols * 0.8), y: 3},  // 向上
  {x: Math.floor(config.cols * 0.6), y: 3},  // 向左
  {x: Math.floor(config.cols * 0.6), y: 8},  // 向下
  {x: Math.floor(config.cols * 0.2), y: 8},  // 向左
  {x: Math.floor(config.cols * 0.2), y: 3}   // 向上回到起点
]

// 添加特效系统
const effects = {
  explosions: [],
  texts: []
}

// 创建爆炸效果
function createExplosion(x, y, size, color) {
  effects.explosions.push({
    x, y, size,
    color,
    alpha: 1,
    frame: 0
  })
}

// 创建浮动文字
function createFloatingText(x, y, text, color) {
  effects.texts.push({
    x, y,
    text,
    color,
    alpha: 1,
    frame: 0
  })
}

// 更新和绘制特效
function updateEffects() {
  // 更新爆炸效果
  for (let i = effects.explosions.length - 1; i >= 0; i--) {
    const explosion = effects.explosions[i]
    explosion.frame++
    explosion.alpha = 1 - explosion.frame / 15
    if (explosion.alpha <= 0) {
      effects.explosions.splice(i, 1)
    }
  }

  // 更新浮动文字
  for (let i = effects.texts.length - 1; i >= 0; i--) {
    const text = effects.texts[i]
    text.frame++
    text.y -= 1
    text.alpha = 1 - text.frame / 30
    if (text.alpha <= 0) {
      effects.texts.splice(i, 1)
    }
  }
}

function drawEffects() {
  // 绘制爆炸效果
  for (const explosion of effects.explosions) {
    ctx.globalAlpha = explosion.alpha
    ctx.fillStyle = explosion.color
    ctx.beginPath()
    ctx.arc(explosion.x, explosion.y, explosion.size * (1 + explosion.frame / 10), 0, Math.PI * 2)
    ctx.fill()
  }

  // 绘制浮动文字
  for (const text of effects.texts) {
    ctx.globalAlpha = text.alpha
    ctx.fillStyle = text.color
    ctx.font = '16px Arial'
    ctx.fillText(text.text, text.x, text.y)
  }
  
  ctx.globalAlpha = 1
}

// 预加载图片资源
const enemyImages = {}
let imagesLoaded = false;
let imagesLoadedCount = 0;
let totalImagesToLoad = 0;

function loadEnemyImages() {
  try {
    // 加载xiaoshe敌人的两帧动画
    const xsFrames = ['xiaoshe1.png', 'xiaoshe2.png'];
    // 加载狐狸敌人的两帧动画
    const huliFrames = ['huli1.png', 'huli2.png'];
    
    totalImagesToLoad = xsFrames.length + huliFrames.length;
    
    // 确保enemyImages对象被初始化
    enemyImages.xiaoshe = [];
    enemyImages.huli = [];
    
    // 加载小蛇各帧
    for (let i = 0; i < xsFrames.length; i++) {
      const img = wx.createImage();
      
      // 添加图片加载成功处理
      img.onload = function() {
        imagesLoadedCount++;
        if (imagesLoadedCount >= totalImagesToLoad) {
          imagesLoaded = true;
          console.log('所有图片加载完成');
        }
      };
      
      // 添加图片加载失败处理
      img.onerror = function() {
        console.error(`图片加载失败: ${xsFrames[i]}`);
        // 继续游戏，使用备用显示方式
        imagesLoadedCount++;
        if (imagesLoadedCount >= totalImagesToLoad) {
          imagesLoaded = true;
        }
      };
      
      // 设置图片源
      img.src = `images/enemies/${xsFrames[i]}`;
      enemyImages.xiaoshe.push(img);
    }
    
    // 加载狐狸各帧
    for (let i = 0; i < huliFrames.length; i++) {
      const img = wx.createImage();
      
      // 添加图片加载成功处理
      img.onload = function() {
        imagesLoadedCount++;
        if (imagesLoadedCount >= totalImagesToLoad) {
          imagesLoaded = true;
          console.log('所有图片加载完成');
        }
      };
      
      // 添加图片加载失败处理
      img.onerror = function() {
        console.error(`图片加载失败: ${huliFrames[i]}`);
        // 继续游戏，使用备用显示方式
        imagesLoadedCount++;
        if (imagesLoadedCount >= totalImagesToLoad) {
          imagesLoaded = true;
        }
      };
      
      // 设置图片源
      img.src = `images/enemies/${huliFrames[i]}`;
      enemyImages.huli.push(img);
    }
    
    // 为其他敌人类型共享图片
    enemyImages.normal = enemyImages.xiaoshe;
    enemyImages.fast = enemyImages.xiaoshe;
    enemyImages.tank = enemyImages.xiaoshe;
    enemyImages.boss = enemyImages.xiaoshe;
  } catch (e) {
    console.error('加载图片时出错:', e);
    // 出错时也要继续游戏
    imagesLoaded = true;
  }
}

// 初始化地图
function initMap() {
  for (let i = 0; i < config.rows; i++) {
    gameState.map[i] = []
    for (let j = 0; j < config.cols; j++) {
      gameState.map[i][j] = 0 // 0表示空地
    }
  }
  
  // 标记路径
  for (let i = 0; i < path.length - 1; i++) {
    const start = path[i]
    const end = path[i + 1]
    
    if (start.x === end.x) {
      // 垂直路径
      const x = start.x
      const minY = Math.min(start.y, end.y)
      const maxY = Math.max(start.y, end.y)
      for (let y = minY; y <= maxY; y++) {
        gameState.map[y][x] = 1 // 1表示路径
      }
    } else {
      // 水平路径
      const y = start.y
      const minX = Math.min(start.x, end.x)
      const maxX = Math.max(start.x, end.x)
      for (let x = minX; x <= maxX; x++) {
        gameState.map[y][x] = 1 // 1表示路径
      }
    }
  }
}

// 绘制地图
function drawMap() {
  // 先绘制底层背景
  ctx.fillStyle = config.backgroundColor;
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  
  // 绘制网格线，让地图区域更清晰
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
  ctx.lineWidth = 0.5;
  
  // 绘制横线
  for (let y = 0; y < config.rows; y++) {
    ctx.beginPath();
    ctx.moveTo(0, y * config.tileSize);
    ctx.lineTo(canvas.width, y * config.tileSize);
    ctx.stroke();
  }
  
  // 绘制竖线
  for (let x = 0; x < config.cols; x++) {
    ctx.beginPath();
    ctx.moveTo(x * config.tileSize, 0);
    ctx.lineTo(x * config.tileSize, canvas.height);
    ctx.stroke();
  }
  
  // 绘制地图格子
  for (let y = 0; y < config.rows; y++) {
    for (let x = 0; x < config.cols; x++) {
      if (gameState.map[y][x] === 1) {
        // 路径
        ctx.fillStyle = config.pathColor;
        ctx.fillRect(
          x * config.tileSize, 
          y * config.tileSize, 
          config.tileSize, 
          config.tileSize
        );
        
        // 在路径上添加一点纹理
        ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
        ctx.beginPath();
        ctx.arc(
          x * config.tileSize + config.tileSize / 2,
          y * config.tileSize + config.tileSize / 2,
          config.tileSize / 6,
          0, Math.PI * 2
        );
        ctx.fill();
      }
    }
  }
}

// 音效系统
const sounds = {
  // 创建音效
  createSound(frequency, duration) {
    const audioContext = wx.createInnerAudioContext()
    // 使用简单的音频数据
    audioContext.src = 'data:audio/wav;base64,UklGRl9vT19XQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YU' + 
      Array(100).fill('A').join('')
    audioContext.volume = 0.3
    audioContext.play()
    setTimeout(() => audioContext.destroy(), duration * 1000)
  },
  
  // 创建持续性音效
  createContinuousSound(frequency, duration, isLoop = false) {
    const audioContext = wx.createInnerAudioContext()
    // 使用简单的音频数据
    audioContext.src = 'data:audio/wav;base64,UklGRl9vT19XQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YU' + 
      Array(100).fill('A').join('')
    audioContext.volume = 0.25
    audioContext.loop = isLoop
    audioContext.play()
    
    if (!isLoop) {
      setTimeout(() => audioContext.destroy(), duration * 1000)
    }
    
    return audioContext
  },
  
  // 停止持续性音效
  stopContinuousSound(audioContext) {
    if (audioContext) {
      audioContext.stop()
      audioContext.destroy()
    }
  },

  // 游戏音效
  shoot() {
    // 发射音效：短促的上升音调
    this.createSound(440, 0.1)
  },
  
  lightning() {
    // 闪电音效：高频率、高强度、多重震动的声音
    // 创建多个不同频率的声音叠加，模拟闪电的噼啪声
    this.createSound(880, 0.1)
    setTimeout(() => this.createSound(1100, 0.05), 50)
    setTimeout(() => this.createSound(990, 0.08), 100)
    setTimeout(() => this.createSound(1300, 0.03), 130)
    setTimeout(() => this.createSound(770, 0.06), 170)
  },
  
  foxDodge() {
    // 狐狸闪避音效：高音调的狐狸叫声
    this.createSound(1200, 0.1)
    setTimeout(() => this.createSound(1500, 0.08), 50)
    setTimeout(() => this.createSound(1800, 0.05), 120)
  },
  
  // 创建持续性闪电音效
  continuousLightning() {
    // 创建闪电的嗡嗡声和噼啪声的组合
    const baseSound = this.createContinuousSound(440, 0.5, true)
    
    // 每隔一小段时间添加额外的闪电音效，增加变化感
    const interval = setInterval(() => {
      const freq = 800 + Math.random() * 500
      this.createSound(freq, 0.05)
    }, 80)
    
    // 返回控制对象
    return {
      baseSound,
      interval,
      stop: function() {
        clearInterval(this.interval)
        sounds.stopContinuousSound(this.baseSound)
      }
    }
  },
  
  hit() {
    // 击中音效：短促的下降音调
    this.createSound(880, 0.05)
  },
  
  explosion() {
    // 爆炸音效：低沉的噪音
    this.createSound(220, 0.2)
  },
  
  upgrade() {
    // 升级音效：上升的音阶
    this.createSound(440, 0.1)
    setTimeout(() => this.createSound(550, 0.1), 100)
    setTimeout(() => this.createSound(660, 0.1), 200)
  },
  
  gameOver() {
    // 游戏结束音效：下降的音阶
    this.createSound(660, 0.2)
    setTimeout(() => this.createSound(550, 0.2), 200)
    setTimeout(() => this.createSound(440, 0.2), 400)
  }
}

// 防御塔类
class Tower {
  constructor(x, y, type) {
    this.x = x
    this.y = y
    this.type = type
    const stats = TOWER_TYPES[type]
    this.range = stats.range
    this.damage = stats.damage
    this.attackSpeed = stats.attackSpeed
    this.lastAttackTime = 0
    this.level = 1
    this.attackType = stats.attackType
    this.targetEnemy = null
    this.hasShield = false
    this.shieldTime = 0
    this.health = config.towerHealth[type] // 塔的生命值
  }

  draw() {
    const stats = TOWER_TYPES[this.type]
    
    // 如果塔有护盾，绘制护盾效果
    if (this.hasShield) {
      const now = Date.now()
      if (now < this.shieldTime) {
        // 计算护盾闪烁透明度
        const alpha = 0.3 + 0.2 * Math.sin(now / 200)
        
        // 绘制护盾圆形
        ctx.globalAlpha = alpha
        ctx.fillStyle = '#88ff88'
        ctx.beginPath()
        ctx.arc(
          (this.x + 0.5) * config.tileSize,
          (this.y + 0.5) * config.tileSize,
          config.tileSize * 0.7,
          0, Math.PI * 2
        )
        ctx.fill()
        ctx.globalAlpha = 1
      } else {
        this.hasShield = false
      }
    }
    
    ctx.fillStyle = stats.color
    
    // 绘制塔身
    ctx.fillRect(
      this.x * config.tileSize + 5,
      this.y * config.tileSize + 5,
      config.tileSize - 10,
      config.tileSize - 10
    )

    // 绘制等级指示器
    ctx.fillStyle = '#ffffff'
    ctx.font = '12px Arial'
    ctx.fillText(
      this.level,
      this.x * config.tileSize + config.tileSize/2 - 3,
      this.y * config.tileSize + config.tileSize/2 + 4
    )
    
    // 绘制塔的生命值条
    const maxHealth = config.towerHealth[this.type]
    const healthPercent = this.health / maxHealth
    
    ctx.fillStyle = '#000000'
    ctx.fillRect(this.x * config.tileSize, this.y * config.tileSize - 5, config.tileSize, 3)
    
    // 根据生命值显示不同颜色
    if (healthPercent > 0.6) {
      ctx.fillStyle = '#00ff00'  // 绿色
    } else if (healthPercent > 0.3) {
      ctx.fillStyle = '#ffff00'  // 黄色
    } else {
      ctx.fillStyle = '#ff0000'  // 红色
    }
    
    ctx.fillRect(
      this.x * config.tileSize, 
      this.y * config.tileSize - 5, 
      config.tileSize * healthPercent, 
      3
    )
    
    // 如果是护盾塔，绘制范围指示
    if (this.type === 'shield') {
      const cooldownPercent = Math.min(1, (Date.now() - this.lastAttackTime) / (TOWER_TYPES.shield.attackSpeed * 1000))
      
      // 绘制范围圆圈
      ctx.strokeStyle = '#4CAF50'
      ctx.globalAlpha = 0.3 + 0.2 * cooldownPercent
      ctx.beginPath()
      ctx.arc(
        (this.x + 0.5) * config.tileSize,
        (this.y + 0.5) * config.tileSize,
        this.range * config.tileSize,
        0, Math.PI * 2 * cooldownPercent
      )
      ctx.stroke()
      ctx.globalAlpha = 1
    }
  }

  findTarget() {
    let bestTarget = null
    let bestValue = -1

    for (const enemy of gameState.enemies) {
      const distance = Math.sqrt(
        Math.pow((this.x + 0.5) - enemy.x / config.tileSize, 2) +
        Math.pow((this.y + 0.5) - enemy.y / config.tileSize, 2)
      )

      if (distance <= this.range) {
        let value = 0
        switch (this.attackType) {
          case 'normal':
            // 普通塔优先攻击最近的敌人
            value = 1 / distance
            break
          case 'snipe':
            // 狙击塔优先攻击血量最高的敌人
            value = enemy.health
            break
          case 'splash':
            // 溅射塔优先攻击敌人密集的地方
            let nearbyEnemies = 0
            for (const otherEnemy of gameState.enemies) {
              const otherDistance = Math.sqrt(
                Math.pow(enemy.x - otherEnemy.x, 2) +
                Math.pow(enemy.y - otherEnemy.y, 2)
              ) / config.tileSize
              if (otherDistance <= TOWER_TYPES[this.type].splashRadius) {
                nearbyEnemies++
              }
            }
            value = nearbyEnemies
            break
          case 'slow':
            // 减速塔优先攻击未被减速的敌人
            value = enemy.slowEffect === 1 ? 1 : 0
            break
        }

        if (value > bestValue) {
          bestValue = value
          bestTarget = enemy
        }
      }
    }

    return bestTarget
  }

  attack() {
    const now = Date.now()
    const stats = TOWER_TYPES[this.type]
    if (now - this.lastAttackTime < stats.attackSpeed * 1000) return

    // 处理不同的塔类型攻击逻辑
    if (this.attackType === 'shield') {
      // 护盾塔的特殊逻辑 - 为范围内的塔提供护盾
      this.lastAttackTime = now
      
      // 播放护盾激活音效
      sounds.upgrade()
      
      // 创建护盾激活效果
      createExplosion(
        (this.x + 0.5) * config.tileSize,
        (this.y + 0.5) * config.tileSize,
        this.range * config.tileSize,
        stats.bulletColor
      )
      
      // 为范围内的塔提供护盾
      for (const tower of gameState.towers) {
        if (tower !== this) {  // 不给自己提供护盾
          const distance = Math.sqrt(
            Math.pow(this.x - tower.x, 2) +
            Math.pow(this.y - tower.y, 2)
          )
          
          if (distance <= this.range) {
            tower.hasShield = true
            tower.shieldTime = now + stats.shieldDuration * this.level
            
            // 记录这个护盾
            gameState.activeShields.push({
              towerId: gameState.towers.indexOf(tower),
              endTime: tower.shieldTime
            })
          }
        }
      }
      
      return
    }
    
    // 闪电塔直接创建闪电链攻击
    if (this.attackType === 'chain') {
      // 寻找目标
      this.targetEnemy = this.findTarget()
      if (!this.targetEnemy) return
    
      // 播放发射音效
      sounds.shoot()
      
      const damage = this.damage * this.level
      
      // 执行闪电链逻辑
      let currentTarget = this.targetEnemy
      let currentDamage = damage
      let hitEnemies = [currentTarget] // 记录已经被闪电链击中的敌人
      
      // 创建从塔到第一个目标的闪电效果
      gameState.lightningEffects.push({
        startX: (this.x + 0.5) * config.tileSize,
        startY: (this.y + 0.5) * config.tileSize,
        endX: currentTarget.x,
        endY: currentTarget.y,
        alpha: 1.0,
        color: stats.bulletColor,
        time: Date.now()
      })
      
      // 创建闪电击中效果
      createExplosion(currentTarget.x, currentTarget.y, 15, stats.bulletColor)
      
      // 对第一个目标造成伤害
      let isCritical = false
      if (currentTarget.takeDamage(currentDamage, isCritical)) {
        // 如果敌人死亡，从数组中移除
        const index = gameState.enemies.indexOf(currentTarget)
        if (index > -1) {
          gameState.enemies.splice(index, 1)
        }
      }
      
      // 寻找并攻击接下来的目标
      for (let chain = 1; chain < stats.chainCount; chain++) {
        // 寻找下一个最近的敌人
        let nextTarget = null
        let closestDistance = stats.chainRange * config.tileSize
        
        for (const enemy of gameState.enemies) {
          // 跳过已经被击中的敌人
          if (hitEnemies.includes(enemy)) continue
          
          const chainDx = enemy.x - currentTarget.x
          const chainDy = enemy.y - currentTarget.y
          const chainDistance = Math.sqrt(chainDx * chainDx + chainDy * chainDy)
          
          if (chainDistance < closestDistance) {
            closestDistance = chainDistance
            nextTarget = enemy
          }
        }
        
        // 如果没有下一个目标，则结束闪电链
        if (!nextTarget) break
        
        // 添加闪电链效果
        gameState.lightningEffects.push({
          startX: currentTarget.x,
          startY: currentTarget.y,
          endX: nextTarget.x,
          endY: nextTarget.y,
          alpha: 1.0,
          color: stats.bulletColor,
          time: Date.now()
        })
        
        // 创建闪电击中效果
        createExplosion(nextTarget.x, nextTarget.y, 15, stats.bulletColor)
        
        // 计算对下一个目标的伤害
        currentDamage *= stats.chainDamageRate
        
        // 对下一个目标造成伤害
        if (nextTarget.takeDamage(currentDamage, false)) {
          // 如果敌人死亡，从数组中移除
          const index = gameState.enemies.indexOf(nextTarget)
          if (index > -1) {
            gameState.enemies.splice(index, 1)
          }
        }
        
        // 添加到已击中列表
        hitEnemies.push(nextTarget)
        
        // 更新当前目标为下一个目标
        currentTarget = nextTarget
      }
      
      this.lastAttackTime = now
      return
    }

    // 寻找目标（非护盾塔和非闪电塔的普通攻击逻辑）
    this.targetEnemy = this.findTarget()
    if (!this.targetEnemy) return

    // 播放发射音效
    sounds.shoot()

    // 创建子弹
    const bullet = {
      x: (this.x + 0.5) * config.tileSize,
      y: (this.y + 0.5) * config.tileSize,
      targetEnemy: this.targetEnemy,
      damage: this.damage * this.level,
      type: this.type,
      attackType: this.attackType
    }

    // 根据攻击类型设置子弹属性
    switch (this.attackType) {
      case 'normal':
        bullet.speed = stats.bulletSpeed
        bullet.size = stats.bulletSize
        bullet.color = stats.bulletColor
        bullet.hitEffect = true
        break
      case 'snipe':
        bullet.speed = stats.bulletSpeed
        bullet.size = stats.bulletSize
        bullet.color = stats.bulletColor
        bullet.criticalChance = stats.criticalChance
        bullet.criticalMultiplier = stats.criticalMultiplier
        break
      case 'splash':
        bullet.speed = stats.bulletSpeed
        bullet.size = stats.bulletSize
        bullet.color = stats.bulletColor
        bullet.splashRadius = stats.splashRadius
        bullet.explosionSize = stats.explosionSize
        break
      case 'slow':
        bullet.speed = stats.bulletSpeed
        bullet.size = stats.bulletSize
        bullet.color = stats.bulletColor
        bullet.slowEffect = stats.slowEffect
        bullet.slowDuration = stats.slowDuration
        bullet.chainReaction = stats.chainReaction
        break
    }

    gameState.bullets.push(bullet)
    this.lastAttackTime = now
  }

  upgrade() {
    if (gameState.gold >= config.towerCost[this.type]) {
      gameState.gold -= config.towerCost[this.type]
      this.level++
      this.damage *= 1.5
      this.range += 0.5
      
      // 播放升级音效
      sounds.upgrade()
      
      return true; // 升级成功
    }
    return false; // 升级失败
  }
}

// 敌人类
class Enemy {
  constructor(type = 'normal') {
    this.type = type
    const stats = ENEMY_TYPES[type]
    this.pathIndex = 0
    this.x = path[0].x * config.tileSize
    this.y = path[0].y * config.tileSize
    this.baseHealth = stats.health
    this.maxHealth = this.baseHealth * (1 + (gameState.wave - 1) * 0.2)
    this.health = this.maxHealth
    this.speed = stats.speed
    this.baseSpeed = stats.speed
    this.value = stats.value
    this.size = stats.size
    this.slowEffect = 1
    this.lastAttackTime = 0
    this.attackDamage = stats.attackDamage || 5  // 每次攻击的伤害
    this.attackSpeed = stats.attackSpeed || 1    // 攻击速度（秒）
    
    // 帧动画相关参数
    this.animationFrame = 0
    this.animationCounter = 0
    this.animationSpeed = stats.animationSpeed || 20 // 控制动画速度
  }

  draw() {
    const stats = ENEMY_TYPES[this.type]
    // 增加尺寸，使小蛇显示更大
    const size = config.tileSize * stats.size * 1.2
    const offset = (config.tileSize - size) / 2
    
    // 更新帧动画计数器
    this.animationCounter++;
    if (this.animationCounter >= this.animationSpeed) {
      this.animationCounter = 0;
      // 切换到下一帧
      this.animationFrame = (this.animationFrame + 1) % (enemyImages[this.type]?.length || 1);
    }
    
    // 使用try-catch防止图片渲染错误导致游戏崩溃
    try {
      // 如果有图片就绘制图片，否则绘制矩形
      if (imagesLoaded && enemyImages[this.type] && enemyImages[this.type].length > 0) {
        const currentFrame = enemyImages[this.type][this.animationFrame];
        if (currentFrame && currentFrame.complete) {
          // 添加一点缩放效果
          const breathEffect = 1 + 0.05 * Math.sin(this.animationCounter / 5);
          
          // 保存当前画布状态
          ctx.save();
          
          // 移动到敌人中心
          ctx.translate(this.x + config.tileSize / 2, this.y + config.tileSize / 2);
          
          // 根据移动方向旋转图像
          if (this.pathIndex < path.length - 1) {
            const targetX = path[this.pathIndex + 1].x * config.tileSize;
            const targetY = path[this.pathIndex + 1].y * config.tileSize;
            const angle = Math.atan2(targetY - this.y, targetX - this.x);
            ctx.rotate(angle);
          }
          
          // 应用呼吸效果
          ctx.scale(breathEffect, breathEffect);
          
          // 为狐狸敌人添加特殊的光环效果
          if (this.type === 'huli') {
            // 绘制光环
            ctx.globalAlpha = 0.4 + 0.2 * Math.sin(this.animationCounter / 10);
            ctx.fillStyle = '#ffcc66'; // 金色光环
            ctx.beginPath();
            ctx.arc(0, 0, size * 0.7, 0, Math.PI * 2);
            ctx.fill();
            
            // 恢复正常透明度
            ctx.globalAlpha = 1;
          }
          
          // 绘制图像
          ctx.drawImage(
            currentFrame,
            -size / 2,  // 中心点偏移
            -size / 2,
            size,
            size
          );
          
          // 恢复画布状态
          ctx.restore();
        } else {
          // 如果图片未加载完成，暂时绘制矩形
          ctx.fillStyle = stats.color;
          ctx.fillRect(this.x + offset, this.y + offset, size, size);
        }
      } else {
        // 绘制敌人
        ctx.fillStyle = stats.color;
        ctx.fillRect(this.x + offset, this.y + offset, size, size);
      }
    } catch (e) {
      // 在渲染出错时，使用简单的方形替代
      console.error('渲染敌人时出错:', e);
      ctx.fillStyle = stats.color;
      ctx.fillRect(this.x + offset, this.y + offset, size, size);
    }

    // 绘制血条背景
    ctx.fillStyle = '#000000'
    ctx.fillRect(this.x, this.y - 10, config.tileSize, 5)
    
    // 绘制当前血量
    ctx.fillStyle = '#ff0000'
    ctx.fillRect(
      this.x,
      this.y - 10,
      config.tileSize * (this.health / this.maxHealth),
      5
    )
    
    // 为狐狸敌人添加特殊标记
    if (this.type === 'huli') {
      ctx.fillStyle = '#ffcc00';
      ctx.font = 'bold 14px Arial';
      ctx.textAlign = 'center';
      ctx.fillText('★', this.x + config.tileSize / 2, this.y - 15);
    }
  }

  move() {
    const stats = ENEMY_TYPES[this.type]
    // 检查是否有塔在敌人附近，如果有，就攻击它
    const now = Date.now()
    if (now - this.lastAttackTime > (stats.attackSpeed * 1000)) {
      // 获取攻击范围
      const attackRange = stats.attackRange * config.tileSize || config.tileSize * 0.8
      
      // 用于存储在范围内的塔
      const towersInRange = []
      
      // 检查哪些塔在攻击范围内
      for (const tower of gameState.towers) {
        const distance = Math.sqrt(
          Math.pow((tower.x + 0.5) * config.tileSize - this.x, 2) +
          Math.pow((tower.y + 0.5) * config.tileSize - this.y, 2)
        )
        
        if (distance < attackRange) {
          towersInRange.push({tower, distance})
        }
      }
      
      // 如果有塔在范围内
      if (towersInRange.length > 0) {
        this.lastAttackTime = now
        
        // 根据敌人类型选择攻击模式
        if (stats.areaAttack) {
          // Boss的范围攻击
          const attackRadius = config.tileSize * 1.5
          
          // 创建大爆炸效果
          createExplosion(
            this.x, 
            this.y, 
            attackRadius, 
            stats.color
          )
          
          // 对范围内所有塔造成伤害
          for (const {tower} of towersInRange) {
            // 如果塔有护盾，伤害减少
            const damageMultiplier = tower.hasShield ? 
              (1 - TOWER_TYPES.shield.shieldStrength) : 1
              
            // 给塔造成伤害
            tower.health -= stats.attackDamage * damageMultiplier
            
            // 显示伤害文本
            createFloatingText(
              (tower.x + 0.5) * config.tileSize,
              (tower.y) * config.tileSize,
              Math.floor(stats.attackDamage * damageMultiplier).toString(),
              "#ff6666"
            )
            
            // 如果是小蛇且能禁用护盾
            if (this.type === 'xiaoshe' && stats.canDisableShield && tower.hasShield) {
              tower.hasShield = false
              createFloatingText(
                (tower.x + 0.5) * config.tileSize,
                (tower.y + 0.3) * config.tileSize,
                "护盾失效!",
                "#88ffff"
              )
            }
            
            // 检查塔是否被摧毁
            this.checkTowerDestroyed(tower)
          }
        } else if (stats.canAttackMultiple) {
          // 坦克可以同时攻击多个塔，但最多3个
          const maxTargets = 3
          const targets = towersInRange.slice(0, maxTargets)
          
          for (const {tower} of targets) {
            // 创建攻击效果
            createExplosion(
              this.x, 
              this.y, 
              config.tileSize * 0.4, 
              stats.color
            )
            
            // 如果塔有护盾，伤害减少
            const damageMultiplier = tower.hasShield ? 
              (1 - TOWER_TYPES.shield.shieldStrength) : 1
              
            // 给塔造成伤害
            tower.health -= stats.attackDamage * damageMultiplier
            
            // 显示伤害文本
            createFloatingText(
              (tower.x + 0.5) * config.tileSize,
              (tower.y) * config.tileSize,
              Math.floor(stats.attackDamage * damageMultiplier).toString(),
              "#ff6666"
            )
            
            // 检查塔是否被摧毁
            this.checkTowerDestroyed(tower)
          }
        } else {
          // 普通敌人只攻击最近的一个塔
          const {tower} = towersInRange.sort((a, b) => a.distance - b.distance)[0]
          
          // 创建攻击效果
          createExplosion(
            this.x, 
            this.y, 
            config.tileSize * 0.4, 
            stats.color
          )
          
          // 如果塔有护盾，伤害减少
          const damageMultiplier = tower.hasShield ? 
            (1 - TOWER_TYPES.shield.shieldStrength) : 1
            
          // 给塔造成伤害
          tower.health -= stats.attackDamage * damageMultiplier
          
          // 显示伤害文本
          createFloatingText(
            (tower.x + 0.5) * config.tileSize,
            (tower.y) * config.tileSize,
            Math.floor(stats.attackDamage * damageMultiplier).toString(),
            "#ff6666"
          )
          
          // 如果是小蛇且能禁用护盾
          if (this.type === 'xiaoshe' && stats.canDisableShield && tower.hasShield) {
            tower.hasShield = false
            createFloatingText(
              (tower.x + 0.5) * config.tileSize,
              (tower.y + 0.3) * config.tileSize,
              "护盾失效!",
              "#88ffff"
            )
          }
          
          // 检查塔是否被摧毁
          this.checkTowerDestroyed(tower)
        }
        
        return false  // 攻击后不移动
      }
    }
    
    // 现有的移动逻辑
    if (this.pathIndex >= path.length - 1) {
      // 敌人到达终点，扣除生命值
      gameState.lives--
      
      // 重置到起点
      this.pathIndex = 0
      this.x = path[0].x * config.tileSize
      this.y = path[0].y * config.tileSize
      return false
    }

    const targetX = path[this.pathIndex + 1].x * config.tileSize
    const targetY = path[this.pathIndex + 1].y * config.tileSize

    const dx = targetX - this.x
    const dy = targetY - this.y
    const distance = Math.sqrt(dx * dx + dy * dy)

    if (distance < this.speed * this.slowEffect) {
      this.pathIndex++
      return false
    }

    this.x += (dx / distance) * this.speed * this.slowEffect
    this.y += (dy / distance) * this.speed * this.slowEffect
    return false
  }
  
  // 辅助方法：检查塔是否被摧毁
  checkTowerDestroyed(tower) {
    if (tower.health <= 0) {
      const index = gameState.towers.indexOf(tower)
      if (index !== -1) {
        // 移除塔
        gameState.towers.splice(index, 1)
        
        // 减少对应类型的塔计数
        gameState.towerCounts[tower.type]--
        
        // 创建塔被摧毁的爆炸效果
        createExplosion(
          (tower.x + 0.5) * config.tileSize,
          (tower.y + 0.5) * config.tileSize,
          config.tileSize,
          TOWER_TYPES[tower.type].color
        )
        
        // 显示塔被摧毁的文本
        createFloatingText(
          (tower.x + 0.5) * config.tileSize,
          (tower.y + 0.5) * config.tileSize,
          "塔被摧毁!",
          "#ff3333"
        )
        
        // 播放摧毁音效
        sounds.explosion()
      }
    }
  }

  takeDamage(damage, isCritical = false) {
    // 处理狐狸的闪避能力
    const stats = ENEMY_TYPES[this.type]
    
    // 狐狸有几率闪避伤害
    if (this.type === 'huli' && stats.dodgeChance && Math.random() < stats.dodgeChance) {
      // 播放狐狸闪避音效
      sounds.foxDodge()
      
      // 显示闪避文本，使其更大、更明显
      createFloatingText(this.x + config.tileSize / 2, this.y, "闪避!", "#ffff00")
      
      // 创建更大、更明显的闪避特效
      createExplosion(
        this.x + config.tileSize / 2,
        this.y + config.tileSize / 2,
        config.tileSize / 1.5, // 更大的效果
        "#ffdd00"  // 更亮的黄色
      )
      
      // 额外添加一圈小爆炸效果
      setTimeout(() => {
        for (let i = 0; i < 4; i++) {
          const angle = Math.PI * 2 * i / 4;
          const offsetX = Math.cos(angle) * config.tileSize / 2;
          const offsetY = Math.sin(angle) * config.tileSize / 2;
          
          createExplosion(
            this.x + config.tileSize / 2 + offsetX,
            this.y + config.tileSize / 2 + offsetY,
            config.tileSize / 4,
            "#ffaa00"
          );
        }
      }, 100);
      
      return false; // 不造成伤害，也不会死亡
    }
    
    // 应用护甲减伤
    const actualDamage = damage * (1 - (stats.armor || 0))
    this.health -= actualDamage // 直接减少生命值，不使用Math.max

    // 创建伤害文字
    const textColor = isCritical ? '#ff0000' : '#ffffff'
    const damageText = isCritical ? `暴击 ${Math.floor(actualDamage)}` : Math.floor(actualDamage).toString()
    createFloatingText(this.x + config.tileSize / 2, this.y, damageText, textColor)

    // 检查是否死亡
    if (this.health <= 0) {
      gameState.gold += this.value
      gameState.score += this.value

      // 死亡特效
      if (stats.deathEffect) {
        createExplosion(
          this.x + config.tileSize / 2,
          this.y + config.tileSize / 2,
          config.tileSize / 2,
          stats.color
        )
      }

      // Boss死亡分裂
      if (stats.minions && this.type === 'boss') {
        for (let i = 0; i < 4; i++) {
          gameState.enemies.push(new Enemy('tank'))
        }
      }

      return true
    }
    return false
  }
}

// 更新子弹
function updateBullets() {
  for (let i = gameState.bullets.length - 1; i >= 0; i--) {
    const bullet = gameState.bullets[i]
    const target = bullet.targetEnemy
    const stats = TOWER_TYPES[bullet.type]

    const dx = target.x + config.tileSize / 2 - bullet.x
    const dy = target.y + config.tileSize / 2 - bullet.y
    const distance = Math.sqrt(dx * dx + dy * dy)

    if (distance < stats.bulletSpeed) {
      // 播放击中音效
      sounds.hit()
      
      // 击中目标
      if (bullet.splashRadius) {
        // 播放爆炸音效
        sounds.explosion()
        // 溅射伤害
        createExplosion(bullet.x, bullet.y, stats.explosionSize, stats.bulletColor)
        for (const enemy of gameState.enemies) {
          const splashDistance = Math.sqrt(
            Math.pow(enemy.x - target.x, 2) +
            Math.pow(enemy.y - target.y, 2)
          ) / config.tileSize

          if (splashDistance <= bullet.splashRadius) {
            enemy.takeDamage(bullet.damage * (1 - splashDistance / bullet.splashRadius))
          }
        }
      } else {
        // 普通伤害
        let isCritical = false
        let damage = bullet.damage

        // 暴击判定
        if (stats.criticalChance && Math.random() < stats.criticalChance) {
          damage *= stats.criticalMultiplier
          isCritical = true
        }

        if (bullet.slowEffect) {
          target.slowEffect = bullet.slowEffect
          setTimeout(() => {
            target.slowEffect = 1
          }, stats.slowDuration)

          // 连锁减速效果
          const chainRadius = stats.chainReaction * config.tileSize
          for (const enemy of gameState.enemies) {
            const chainDistance = Math.sqrt(
              Math.pow(enemy.x - target.x, 2) +
              Math.pow(enemy.y - target.y, 2)
            )
            if (chainDistance <= chainRadius && enemy !== target) {
              enemy.slowEffect = bullet.slowEffect * 0.7
              setTimeout(() => {
                enemy.slowEffect = 1
              }, stats.slowDuration * 0.7)
            }
          }
        }

        if (target.takeDamage(damage, isCritical)) {
          // 如果敌人死亡，从数组中移除
          const index = gameState.enemies.indexOf(target)
          if (index > -1) {
            gameState.enemies.splice(index, 1)
          }
        }
      }

      // 击中特效
      if (stats.hitEffect) {
        createExplosion(bullet.x, bullet.y, stats.bulletSize * 2, stats.bulletColor)
      }

      gameState.bullets.splice(i, 1)
    } else {
      bullet.x += (dx / distance) * stats.bulletSpeed
      bullet.y += (dy / distance) * stats.bulletSpeed
    }
  }
  
  // 更新闪电链特效
  for (let i = gameState.lightningEffects.length - 1; i >= 0; i--) {
    const effect = gameState.lightningEffects[i]
    const elapsed = Date.now() - effect.time
    
    // 闪电效果持续时间较短(200毫秒)，营造出电闪的感觉
    if (elapsed > 200) {
      gameState.lightningEffects.splice(i, 1)
    } else {
      // 更新透明度
      effect.alpha = 1.0 - (elapsed / 200)
    }
  }
}

// 绘制子弹
function drawBullets() {
  for (const bullet of gameState.bullets) {
    const stats = TOWER_TYPES[bullet.type]
    ctx.fillStyle = stats.bulletColor
    
    switch (bullet.type) {
      case 'basic':
        // 基础塔：黄色能量球
        ctx.beginPath()
        ctx.arc(bullet.x, bullet.y, stats.bulletSize, 0, Math.PI * 2)
        ctx.fill()
        // 添加光晕效果
        ctx.globalAlpha = 0.3
        ctx.beginPath()
        ctx.arc(bullet.x, bullet.y, stats.bulletSize * 1.5, 0, Math.PI * 2)
        ctx.fill()
        ctx.globalAlpha = 1
        break
        
      case 'sniper':
        // 狙击塔：红色激光
        ctx.beginPath()
        ctx.moveTo(bullet.x, bullet.y)
        ctx.lineTo(bullet.x + (bullet.targetEnemy.x - bullet.x) * 0.1,
                  bullet.y + (bullet.targetEnemy.y - bullet.y) * 0.1)
        ctx.lineWidth = stats.bulletSize
        ctx.stroke()
        // 添加激光头
        ctx.beginPath()
        ctx.arc(bullet.x, bullet.y, stats.bulletSize * 1.5, 0, Math.PI * 2)
        ctx.fill()
        break
        
      case 'splash':
        // 溅射塔：粉色魔法弹
        ctx.beginPath()
        ctx.moveTo(bullet.x, bullet.y)
        ctx.lineTo(bullet.x + (bullet.targetEnemy.x - bullet.x) * 0.1,
                  bullet.y + (bullet.targetEnemy.y - bullet.y) * 0.1)
        ctx.lineWidth = stats.bulletSize
        ctx.stroke()
        // 添加魔法效果
        ctx.beginPath()
        ctx.arc(bullet.x, bullet.y, stats.bulletSize * 1.2, 0, Math.PI * 2)
        ctx.fill()
        // 添加魔法光环
        ctx.globalAlpha = 0.2
        ctx.beginPath()
        ctx.arc(bullet.x, bullet.y, stats.bulletSize * 2, 0, Math.PI * 2)
        ctx.fill()
        ctx.globalAlpha = 1
        break
        
      case 'slow':
        // 减速塔：青色冰晶
        ctx.save()
        ctx.translate(bullet.x, bullet.y)
        ctx.rotate(Math.atan2(bullet.targetEnemy.y - bullet.y,
                            bullet.targetEnemy.x - bullet.x))
        // 绘制冰晶形状
        ctx.beginPath()
        ctx.moveTo(0, -stats.bulletSize)
        ctx.lineTo(stats.bulletSize, 0)
        ctx.lineTo(0, stats.bulletSize)
        ctx.lineTo(-stats.bulletSize, 0)
        ctx.closePath()
        ctx.fill()
        // 添加冰晶效果
        ctx.globalAlpha = 0.3
        ctx.beginPath()
        ctx.moveTo(0, -stats.bulletSize * 1.5)
        ctx.lineTo(stats.bulletSize * 1.5, 0)
        ctx.lineTo(0, stats.bulletSize * 1.5)
        ctx.lineTo(-stats.bulletSize * 1.5, 0)
        ctx.closePath()
        ctx.fill()
        ctx.restore()
        break
    }
  }
}

// 生成新的敌人波次
function spawnWave() {
  // 减少敌人总数量，从每波2*wave减为每波1.5*wave
  const enemyCount = Math.floor(gameState.wave * 1.5)
  let enemyTypes = ['normal']
  
  // 根据波数解锁新的敌人类型
  if (gameState.wave >= 3) enemyTypes.push('fast')
  if (gameState.wave >= 5) enemyTypes.push('tank')
  if (gameState.wave >= 7) enemyTypes.push('xiaoshe')  // 添加新的敌人类型
  if (gameState.wave >= 10 && gameState.wave % 5 === 0) enemyTypes.push('boss')

  // 单独处理狐狸敌人的生成逻辑
  const spawnHuli = gameState.wave >= 3;

  for (let i = 0; i < enemyCount; i++) {
    setTimeout(() => {
      if (!gameState.gameOver) {
        // 常规敌人生成
        const randomType = enemyTypes[Math.floor(Math.random() * enemyTypes.length)]
        gameState.enemies.push(new Enemy(randomType))
      }
    }, i * 1000)
  }
  
  // 如果达到条件，额外生成1-2只狐狸敌人
  if (spawnHuli) {
    // 根据波数决定生成的狐狸数量，最多2只
    const huliCount = Math.min(2, Math.floor(gameState.wave / 3));
    
    // 在常规敌人之后生成狐狸，使其出现时机更有战略性
    for (let i = 0; i < huliCount; i++) {
      setTimeout(() => {
        if (!gameState.gameOver) {
          // 生成狐狸敌人
          gameState.enemies.push(new Enemy('huli'))
          
          // 生成浮动文本提示玩家
          if (gameState.enemies.length > 0) {
            const lastEnemy = gameState.enemies[gameState.enemies.length - 1];
            createFloatingText(lastEnemy.x, lastEnemy.y - 30, "狐狸出现!", "#ff9933")
          }
        }
      }, (enemyCount + i) * 1000 + 500)  // 在常规敌人之后生成，有额外延迟
    }
  }
}

// 优化游戏循环以避免过度渲染
let lastFrameTime = 0;
const targetFPS = 60;
const frameInterval = 1000 / targetFPS;

// 游戏主循环
function gameLoop(timestamp) {
  // 计算帧间隔时间
  if (!lastFrameTime) lastFrameTime = timestamp;
  const deltaTime = timestamp - lastFrameTime;
  
  // 如果距离上一帧时间过短，跳过这一帧
  if (deltaTime < frameInterval - 1) {
    requestAnimationFrame(gameLoop);
    return;
  }
  
  // 更新时间
  lastFrameTime = timestamp;
  
  try {
    if (gameState.showIntro) {
      drawIntro()
    } else if (!gameState.gameOver) {
      // 清除画布
      ctx.fillStyle = config.backgroundColor
      ctx.fillRect(0, 0, canvas.width, canvas.height)

      // 绘制地图
      drawMap()
      
      // 绘制建造系统视觉元素
      drawBuildSystem()

      // 更新和绘制防御塔
      for (const tower of gameState.towers) {
        tower.attack()
        tower.draw()
      }

      // 更新和绘制敌人
      for (let i = gameState.enemies.length - 1; i >= 0; i--) {
        const enemy = gameState.enemies[i]
        if (enemy.move()) {
          gameState.enemies.splice(i, 1)
        }
        enemy.draw()
      }

      // 更新和绘制子弹
      updateBullets()
      drawBullets()
      
      // 绘制闪电链效果
      ctx.lineWidth = 3
      for (const effect of gameState.lightningEffects) {
        // 设置闪电颜色和透明度
        ctx.strokeStyle = effect.color
        ctx.globalAlpha = effect.alpha
        
        // 绘制锯齿状闪电线
        ctx.beginPath()
        ctx.moveTo(effect.startX, effect.startY)
        
        // 使用更多的段数和更大的偏移来创建更逼真的闪电效果
        const segments = 8
        const mainPath = []
        
        // 首先创建主路径
        for (let i = 1; i <= segments; i++) {
          const ratio = i / segments
          const nextX = effect.startX + (effect.endX - effect.startX) * ratio
          const nextY = effect.startY + (effect.endY - effect.startY) * ratio
          
          // 添加随机偏移，使闪电看起来不规则
          const offset = 12
          const randomX = (Math.random() - 0.5) * offset * 2
          const randomY = (Math.random() - 0.5) * offset * 2
          
          mainPath.push({
            x: nextX + randomX,
            y: nextY + randomY
          })
        }
        
        // 绘制主路径
        for (const point of mainPath) {
          ctx.lineTo(point.x, point.y)
        }
        ctx.stroke()
        
        // 添加分支闪电
        const branchCount = 2
        for (let i = 0; i < branchCount; i++) {
          // 从主路径上随机选择一个点作为分支起点
          const branchStartIndex = Math.floor(Math.random() * (segments - 2)) + 1
          const branchStart = mainPath[branchStartIndex]
          
          const branchLength = Math.random() * 40 + 20
          const branchAngle = Math.random() * Math.PI * 2
          
          ctx.beginPath()
          ctx.moveTo(branchStart.x, branchStart.y)
          
          // 创建分支闪电
          let lastX = branchStart.x
          let lastY = branchStart.y
          const branchSegments = 3
          
          for (let j = 1; j <= branchSegments; j++) {
            const ratio = j / branchSegments
            const distance = branchLength * ratio
            const nextX = branchStart.x + Math.cos(branchAngle) * distance
            const nextY = branchStart.y + Math.sin(branchAngle) * distance
            
            // 添加随机偏移
            const offset = 8
            const randomX = (Math.random() - 0.5) * offset * 2
            const randomY = (Math.random() - 0.5) * offset * 2
            
            ctx.lineTo(nextX + randomX, nextY + randomY)
          }
          
          // 绘制分支
          ctx.globalAlpha = effect.alpha * 0.7 // 分支透明度降低
          ctx.stroke()
        }
        
        // 恢复全局透明度
        ctx.globalAlpha = 1.0
        
        // 添加闪电起点和终点的发光效果
        ctx.fillStyle = effect.color
        ctx.globalAlpha = effect.alpha * 0.6
        
        // 起点发光
        ctx.beginPath()
        ctx.arc(effect.startX, effect.startY, 6, 0, Math.PI * 2)
        ctx.fill()
        
        // 终点发光
        ctx.beginPath()
        ctx.arc(effect.endX, effect.endY, 8, 0, Math.PI * 2)
        ctx.fill()
        
        ctx.globalAlpha = 1.0
      }

      // 检查是否需要生成新的波次
      if (gameState.enemies.length === 0) {
        gameState.wave++
        spawnWave()
      }

      // 检查游戏是否结束
      if (gameState.lives <= 0 && !gameState.gameOver) {
        gameState.gameOver = true
        sounds.gameOver()
      }

      // 更新和绘制特效
      updateEffects()
      drawEffects()
    }

    // 绘制UI
    if (!gameState.showIntro) {
      drawUI()
    }
  } catch (e) {
    console.error('游戏循环出错:', e);
    // 显示但不中断游戏
    createFloatingText(
      canvas.width / 2,
      canvas.height / 2,
      "游戏运行出错",
      "#ff0000"
    );
  }

  // 继续下一帧
  requestAnimationFrame(gameLoop);
}

// 添加触摸移动事件监听
wx.onTouchMove(function(e) {
  if (e.touches.length > 0) {
    const touch = e.touches[0];
    gameState.mouseX = touch.clientX;
    gameState.mouseY = touch.clientY;
  }
});

// 绘制UI
function drawUI() {
  // 创建半透明背景以增加文字可读性
  ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
  ctx.fillRect(0, 0, 250, 120);
  
  // 绘制基本信息
  ctx.fillStyle = '#ffffff'; // 改为白色使在半透明背景上更清晰
  ctx.font = '20px Arial'
  ctx.fillText(`金币: ${gameState.gold}`, 10, 30)
  ctx.fillText(`生命: ${gameState.lives}`, 10, 60)
  ctx.fillText(`波数: ${gameState.wave}`, 10, 90)
  ctx.fillText(`分数: ${gameState.score}`, 10, 120)
  
  // 绘制建造模式切换按钮 - 放大并使颜色更明显
  ctx.fillStyle = gameState.placementMode ? '#4CAF50' : '#555555'
  ctx.fillRect(canvas.width - 130, 10, 120, 45)
  ctx.fillStyle = '#ffffff'
  ctx.font = '16px Arial'
  ctx.textAlign = 'center'
  ctx.fillText(gameState.placementMode ? '退出建造模式' : '进入建造模式', canvas.width - 70, 37)
  ctx.textAlign = 'left'

  // 绘制塔选择菜单背景 - 半透明黑色背景
  ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
  ctx.fillRect(0, canvas.height - 70, canvas.width, 70);
  
  // 绘制塔选择菜单 - 增大尺寸和间距
  const menuY = canvas.height - 70
  Object.entries(TOWER_TYPES).forEach(([type, stats], index) => {
    const menuX = 10 + index * 80  // 增大间距
    
    // 绘制塔的数量限制信息
    const currentCount = gameState.towerCounts[type]
    const maxCount = config.towerLimits[type]
    
    // 如果达到上限，显示灰色
    if (currentCount >= maxCount) {
      ctx.fillStyle = '#888888'  // 灰色表示达到上限
    } else {
      ctx.fillStyle = stats.color
    }
    
    // 绘制更大的选择框
    ctx.fillRect(menuX, menuY, 70, 60)
    
    // 绘制塔的名字
    ctx.fillStyle = '#ffffff'
    ctx.font = '14px Arial'
    ctx.textAlign = 'center'
    let towerName = ''
    switch(type) {
      case 'basic':
        towerName = '基础塔'
        break
      case 'lightning':
        towerName = '闪电塔'
        break
      case 'sniper':
        towerName = '狙击塔'
        break
      case 'splash':
        towerName = '溅射塔'
        break
      case 'slow':
        towerName = '减速塔'
        break
      case 'shield':
        towerName = '护盾塔'
        break
    }
    ctx.fillText(towerName, menuX + 35, menuY + 20)
    
    // 绘制价格和数量信息
    ctx.fillText(`${config.towerCost[type]} (${currentCount}/${maxCount})`, menuX + 35, menuY + 45)
    
    if (type === gameState.selectedTowerType) {
      ctx.strokeStyle = '#ffffff'
      ctx.lineWidth = 3  // 加粗选中边框
      ctx.strokeRect(menuX, menuY, 70, 60)

      // 显示当前选中塔的技能说明 - 增加背景提高可读性
      ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
      ctx.fillRect(10, menuY - 45, 400, 35);
      
      ctx.fillStyle = '#ffffff'
      ctx.font = '14px Arial'
      ctx.textAlign = 'left'
      let skillDesc = ''
      switch(type) {
        case 'basic':
          skillDesc = '技能：普通攻击，平衡的伤害和攻速'
          break
        case 'lightning':
          skillDesc = '技能：闪电链攻击，对多个敌人造成伤害'
          break
        case 'sniper':
          skillDesc = '技能：远距离高伤害，30%概率2.5倍暴击'
          break
        case 'splash':
          skillDesc = '技能：范围伤害，适合群战'
          break
        case 'slow':
          skillDesc = '技能：减速敌人，连锁减速效果'
          break
        case 'shield':
          skillDesc = '技能：为周围塔提供护盾，减少50%伤害'
          break
      }
      ctx.fillText(skillDesc, 10, menuY - 20)
      
      // 显示放置限制提示
      if (gameState.towerCounts[type] >= config.towerLimits[type]) {
        ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
        ctx.fillRect(10, menuY - 80, 250, 35);
        
        ctx.fillStyle = '#ff6666'
        ctx.fillText(`已达到最大数量 (${maxCount})`, 10, menuY - 55)
      }
    }
  })

  if (gameState.gameOver) {
    ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'
    ctx.fillRect(0, 0, canvas.width, canvas.height)
    ctx.fillStyle = '#ffffff'
    ctx.font = '40px Arial'
    ctx.textAlign = 'center'
    ctx.fillText('游戏结束', canvas.width / 2, canvas.height / 2)
    ctx.font = '24px Arial'
    ctx.fillText(`最终分数: ${gameState.score}`, canvas.width / 2, canvas.height / 2 + 40)
    
    // 添加重新开始按钮
    ctx.fillStyle = '#4CAF50'
    ctx.fillRect(canvas.width / 2 - 60, canvas.height / 2 + 60, 120, 40)
    ctx.fillStyle = '#ffffff'
    ctx.fillText('重新开始', canvas.width / 2, canvas.height / 2 + 85)
    ctx.textAlign = 'left'
  }
  
  // 显示放置模式状态 - 更明显的提示
  if (gameState.placementMode) {
    // 顶部提示条 - 更加醒目
    ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'
    ctx.fillRect(0, 0, 350, 35)
    ctx.fillStyle = '#ffffff'
    ctx.font = '18px Arial'
    ctx.textAlign = 'left'
    ctx.fillText('📍 建造模式: 点击任意空地放置塔 (绿色区域)', 10, 25)
    
    // 底部显示当前选中的塔类型信息
    const type = gameState.selectedTowerType;
    const stats = TOWER_TYPES[type];
    const cost = config.towerCost[type];
    const count = gameState.towerCounts[type];
    const limit = config.towerLimits[type];
    
    ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
    ctx.fillRect(10, canvas.height - 120, 250, 60);
    
    // 显示塔名和数量
    ctx.fillStyle = '#ffffff';
    ctx.font = '20px Arial';
    let towerName = '';
    switch(type) {
      case 'basic': towerName = '基础塔'; break;
      case 'lightning': towerName = '闪电塔'; break;
      case 'sniper': towerName = '狙击塔'; break;
      case 'splash': towerName = '溅射塔'; break;
      case 'slow': towerName = '减速塔'; break;
      case 'shield': towerName = '护盾塔'; break;
    }
    ctx.fillText(`选中: ${towerName} (${count}/${limit})`, 20, canvas.height - 90);
    
    // 显示价格
    ctx.fillStyle = gameState.gold >= cost ? '#00ff00' : '#ff6666';
    ctx.fillText(`价格: ${cost} 金币`, 20, canvas.height - 60);
  }
}

// 绘制介绍界面
function drawIntro() {
  ctx.fillStyle = 'rgba(0, 0, 0, 0.8)'
  ctx.fillRect(0, 0, canvas.width, canvas.height)
  
  ctx.fillStyle = '#ffffff'
  ctx.font = '24px Arial'
  ctx.textAlign = 'center'
  
  // 标题
  ctx.fillText('塔防游戏', canvas.width / 2, 100)
  
  // 游戏说明
  ctx.font = '18px Arial'
  ctx.fillText('游戏说明：', canvas.width / 2, 150)
  
  const instructions = [
    '1. 点击底部菜单选择防御塔类型',
    '2. 点击任意绿色区域放置防御塔',
    '3. 点击已放置的防御塔进行升级',
    '4. 阻止敌人到达终点',
    '5. 收集金币，提升防御能力',
    '6. 每种塔都有数量限制，请合理规划'
  ]
  
  instructions.forEach((text, index) => {
    ctx.fillText(text, canvas.width / 2, 200 + index * 30)
  })
  
  // 建造系统说明
  ctx.font = '20px Arial'
  ctx.fillText('建造系统：', canvas.width / 2, 400)
  
  const buildInfo = [
    '· 所有非路径区域都可以建造塔（绿色区域）',
    '· 建造塔后会自动消耗金币',
    '· 基础塔限制为10个，狙击塔和溅射塔限制为5个',
    '· 减速塔限制为5个，护盾塔限制为3个',
    '· 游戏一开始会自动进入建造模式'
  ]
  
  buildInfo.forEach((text, index) => {
    ctx.fillText(text, canvas.width / 2, 430 + index * 30)
  })
  
  // 防御塔介绍
  ctx.font = '20px Arial'
  ctx.fillText('防御塔介绍：', canvas.width / 2, 600)
  
  const towerInfo = [
    '基础塔：黄色能量球，平衡的伤害和攻击速度',
    '闪电塔：蓝色闪电球，对多个敌人造成伤害',
    '狙击塔：红色激光，远距离高伤害，可能暴击',
    '溅射塔：粉色魔法弹，范围伤害，适合群战',
    '减速塔：青色冰晶，减速敌人，连锁效果',
    '护盾塔：绿色护盾，为周围塔提供防护'
  ]
  
  towerInfo.forEach((text, index) => {
    ctx.fillText(text, canvas.width / 2, 630 + index * 30)
  })

  // 敌人说明
  ctx.font = '20px Arial'
  ctx.fillText('敌人介绍：', canvas.width / 2, 780)
  
  const enemyInfo = [
    '普通敌人：基础攻击力，会攻击防御塔',
    '快速敌人：移动快，攻击频繁但伤害低',
    '坦克敌人：生命高，能同时攻击多个塔',
    'Boss敌人：超强攻击，可进行范围攻击',
    '小蛇敌人：能破坏塔的护盾效果'
  ]
  
  enemyInfo.forEach((text, index) => {
    ctx.fillText(text, canvas.width / 2, 810 + index * 30)
  })
  
  // 战略建议
  ctx.font = '20px Arial'
  ctx.fillText('战略建议：', canvas.width / 2, 960)
  
  const strategyInfo = [
    '· 在路径附近建立防御阵地，拦截敌人',
    '· 优先升级现有塔，而不是建造更多塔',
    '· 利用护盾塔保护高伤害的塔',
    '· 在不同波次到来前做好规划'
  ]
  
  strategyInfo.forEach((text, index) => {
    ctx.fillText(text, canvas.width / 2, 990 + index * 30)
  })
  
  // 开始按钮
  ctx.fillStyle = '#4CAF50'
  ctx.fillRect(canvas.width / 2 - 60, canvas.height - 100, 120, 40)
  ctx.fillStyle = '#ffffff'
  ctx.font = '20px Arial'
  ctx.fillText('开始游戏', canvas.width / 2, canvas.height - 75)
  
  ctx.textAlign = 'left'
}

// 在游戏初始化前添加游戏辅助函数
// 检查某个位置是否在路径上或紧邻路径
function isNearPath(x, y, maxDistance = 1) {
  // 检查是否在地图范围内
  if (x < 0 || x >= config.cols || y < 0 || y >= config.rows) {
    return false;
  }
  
  // 检查该位置是否是路径
  if (gameState.map[y][x] === 1) {
    return true;
  }
  
  // 检查周围的格子
  for (let dy = -maxDistance; dy <= maxDistance; dy++) {
    for (let dx = -maxDistance; dx <= maxDistance; dx++) {
      const nx = x + dx;
      const ny = y + dy;
      
      // 确保坐标在地图范围内
      if (nx >= 0 && nx < config.cols && ny >= 0 && ny < config.rows) {
        // 如果周围有路径，返回true
        if (gameState.map[ny][nx] === 1) {
          return true;
        }
      }
    }
  }
  
  return false;
}

// 初始化建造系统 - 极简版本
function initBuildSystem() {
  // 初始化可建造区域网格 - 全地图可建造策略
  gameState.buildableGrid = []
  for (let y = 0; y < config.rows; y++) {
    gameState.buildableGrid[y] = []
    for (let x = 0; x < config.cols; x++) {
      // 只要不是路径，就设为可建造
      gameState.buildableGrid[y][x] = (gameState.map[y][x] === 0)
    }
  }
  
  // 简化:保留一些建造节点作为视觉指示和参考点
  const nodePositions = [
    {x: 2, y: 5},
    {x: 4, y: 2},
    {x: Math.floor(config.cols * 0.75), y: 5},
    {x: Math.floor(config.cols * 0.65), y: 2},
    {x: Math.floor(config.cols * 0.3), y: 10},
    {x: Math.floor(config.cols * 0.6), y: 10},
    {x: Math.floor(config.cols * 0.3), y: 14},
    {x: Math.floor(config.cols * 0.7), y: 14}
  ];
  
  // 存储建造节点 - 仅供视觉显示，不再影响建造逻辑
  gameState.buildNodes = nodePositions;
}

// 绘制建造系统视觉元素
function drawBuildSystem() {
  // 获取当前时间戳以减少重复计算
  const now = Date.now();
  const pulseVal = Math.sin(now / 400);
  
  // 如果处于放置模式，绘制可建造区域提示
  if ((gameState.placementMode || config.buildingSystem.mobileOptimized) && config.buildingSystem.showGrid) {
    // 绘制可建造区域 - 所有非路径区域都可建造
    for (let y = 0; y < config.rows; y++) {
      for (let x = 0; x < config.cols; x++) {
        // 如果不是路径，而且没有塔，就标记为可建造
        if (gameState.map[y][x] === 0 && 
            !gameState.towers.some(tower => tower.x === x && tower.y === y)) {
          
          // 绿色半透明表示可建造区域
          ctx.fillStyle = config.buildingSystem.gridColor;
          
          // 添加呼吸效果，让可建造区域更显眼
          if (config.buildingSystem.highlightOnPlacement) {
            const pulse = 0.2 * pulseVal; // 使用预计算的值
            ctx.globalAlpha = 0.5 + pulse; // 增加基础透明度更明显
          }
          
          // 绘制稍小一点的方块，留出边框
          ctx.fillRect(
            x * config.tileSize + 2, 
            y * config.tileSize + 2, 
            config.tileSize - 4, 
            config.tileSize - 4
          );
          
          // 恢复透明度
          ctx.globalAlpha = 1;
        }
      }
    }
    
    // 当鼠标悬停在可建造区域时显示预览
    if (gameState.mouseX !== undefined && gameState.mouseY !== undefined) {
      const gridX = Math.floor(gameState.mouseX / config.tileSize);
      const gridY = Math.floor(gameState.mouseY / config.tileSize);
      
      if (gridX >= 0 && gridX < config.cols && gridY >= 0 && gridY < config.rows) {
        // 简化预览判断条件 - 只要不是路径且没有塔就可以预览
        if (gameState.map[gridY][gridX] === 0 &&
            !gameState.towers.some(tower => tower.x === gridX && tower.y === gridY)) {
          
          // 显示塔的预览
          ctx.fillStyle = TOWER_TYPES[gameState.selectedTowerType].color;
          ctx.globalAlpha = 0.7; // 增加透明度使预览更明显
          ctx.fillRect(
            gridX * config.tileSize + 5, 
            gridY * config.tileSize + 5, 
            config.tileSize - 10, 
            config.tileSize - 10
          );
          
          // 添加外边框，使预览更明显
          ctx.strokeStyle = '#ffffff';
          ctx.lineWidth = 2;
          ctx.strokeRect(
            gridX * config.tileSize + 5, 
            gridY * config.tileSize + 5, 
            config.tileSize - 10, 
            config.tileSize - 10
          );
          
          ctx.globalAlpha = 1;
          
          // 添加文本提示
          if (config.buildingSystem.mobileOptimized) {
            ctx.fillStyle = '#ffffff';
            ctx.font = '14px Arial';
            ctx.textAlign = 'center';
            ctx.fillText(
              '点击建造',
              gridX * config.tileSize + config.tileSize/2,
              gridY * config.tileSize - 5
            );
            ctx.textAlign = 'left';
          }
        }
      }
    }
  }
  
  // 绘制建造节点 - 现在只是装饰性的，不再影响建造逻辑
  for (const node of gameState.buildNodes) {
    // 添加一个脉动效果变量，使节点更明显
    const pulseSize = 12 + 2 * pulseVal;
    
    // 绘制内圈填充
    ctx.fillStyle = 'rgba(255, 215, 0, 0.5)';
    ctx.beginPath();
    ctx.arc(
      (node.x + 0.5) * config.tileSize,
      (node.y + 0.5) * config.tileSize,
      8,
      0, Math.PI * 2
    );
    ctx.fill();
    
    // 绘制外圈
    ctx.strokeStyle = config.buildingSystem.nodeColor;
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.arc(
      (node.x + 0.5) * config.tileSize,
      (node.y + 0.5) * config.tileSize,
      pulseSize,
      0, Math.PI * 2
    );
    ctx.stroke();
  }
}

// 完整修复触摸事件处理器
wx.onTouchStart(function(e) {
  try {
    if (e.touches.length > 0) {
      const touch = e.touches[0];
      gameState.mouseX = touch.clientX;
      gameState.mouseY = touch.clientY;
    } else {
      return; // 没有触摸点，直接返回
    }
    
    // 处理游戏结束状态的重新开始按钮
    if (gameState.gameOver) {
      const touch = e.touches[0];
      // 检查是否点击了重新开始按钮
      if (touch.clientX >= canvas.width / 2 - 60 &&
          touch.clientX <= canvas.width / 2 + 60 &&
          touch.clientY >= canvas.height / 2 + 60 &&
          touch.clientY <= canvas.height / 2 + 100) {
        // 重新初始化游戏
        init();
        return;
      }
      return; // 如果是游戏结束状态但没点击重新开始，不处理其他点击
    }
    
    if (gameState.showIntro) {
      const touch = e.touches[0]
      // 检查是否点击了开始按钮
      if (touch.clientX >= canvas.width / 2 - 60 &&
          touch.clientX <= canvas.width / 2 + 60 &&
          touch.clientY >= canvas.height - 100 &&
          touch.clientY <= canvas.height - 60) {
        gameState.showIntro = false;
        
        // 关闭介绍界面时自动进入建造模式
        if (config.buildingSystem.autoEnterBuildMode) {
          gameState.placementMode = true;
          gameState.selectedTowerType = 'basic'; // 默认选择基础塔
          
          // 添加提示文字
          setTimeout(() => {
            createFloatingText(
              canvas.width / 2,
              canvas.height / 2 - 50,
              "点击绿色区域建造塔防! 开始防御!",
              "#00ff00"
            );
          }, 500);
        }
      }
      return
    }

    const touch = e.touches[0]
    
    // 检查是否点击了建造模式切换按钮
    if (touch.clientX >= canvas.width - 130 && touch.clientX <= canvas.width - 10 &&
        touch.clientY >= 10 && touch.clientY <= 55) {
      gameState.placementMode = !gameState.placementMode
      
      // 如果进入建造模式，显示提示
      if (gameState.placementMode) {
        createFloatingText(
          canvas.width / 2,
          canvas.height / 2 - 50,
          "请选择建造位置（绿色区域）",
          "#00ff00"
        )
      }
      return
    }
    
    const x = Math.floor(touch.clientX / config.tileSize)
    const y = Math.floor(touch.clientY / config.tileSize)

    // 检查是否点击了塔选择菜单
    if (touch.clientY >= canvas.height - 70) {
      const menuIndex = Math.floor((touch.clientX - 10) / 80)
      const towerTypes = Object.keys(TOWER_TYPES)
      if (menuIndex >= 0 && menuIndex < towerTypes.length) {
        const selectedType = towerTypes[menuIndex]
        // 只有未达到上限时才能选择
        if (gameState.towerCounts[selectedType] < config.towerLimits[selectedType]) {
          gameState.selectedTowerType = selectedType
          // 进入放置模式
          gameState.placementMode = true
          
          // 显示建造提示
          createFloatingText(
            canvas.width / 2,
            canvas.height / 2 - 50,
            "请选择建造位置（绿色区域）",
            "#00ff00"
          )
        } else {
          // 创建提示文字
          createFloatingText(
            touch.clientX,
            touch.clientY - 20,
            "已达到最大数量!",
            "#ff0000"
          )
        }
      }
      return
    }

    // 检查是否点击了现有的塔（升级）
    const existingTower = gameState.towers.find(tower => tower.x === x && tower.y === y)
    if (existingTower) {
      // 显示塔的详细信息
      const type = existingTower.type
      const stats = TOWER_TYPES[type]
      
      const upgradeResult = existingTower.upgrade()
      
      // 如果成功升级，显示升级信息
      if (upgradeResult) {
        createFloatingText(
          (existingTower.x + 0.5) * config.tileSize,
          (existingTower.y) * config.tileSize - 15,
          `升级到 Lv.${existingTower.level}`,
          "#ffff00"
        )
      } else {
        // 如果金币不足，显示提示
        createFloatingText(
          (existingTower.x + 0.5) * config.tileSize,
          (existingTower.y) * config.tileSize - 15,
          `金币不足! 需要${config.towerCost[type]}金币`,
          "#ff9900"
        )
      }
      return
    }

    // 简化放置新塔的逻辑 - 减少条件检查，优先考虑建造位置
    if (x >= 0 && x < config.cols && y >= 0 && y < config.rows) {
      // 总是考虑放置，即使不在放置模式也尝试建造
      // 在移动设备上，这样更容易操作
      
      // 1. 检查是否能够建造 - 简化条件，优先考虑位置是否有效
      const canBuild = gameState.map[y][x] === 0 && // 不是路径
        !gameState.towers.some(tower => tower.x === x && tower.y === y); // 没有其他塔
      
      // 2. 检查金币是否足够
      const hasMoney = gameState.gold >= config.towerCost[gameState.selectedTowerType];
      
      // 3. 检查塔数量是否达到上限
      const withinLimit = gameState.towerCounts[gameState.selectedTowerType] < 
        config.towerLimits[gameState.selectedTowerType];
      
      // 全部条件满足才能建造 - 简化可建造区域检查
      if (canBuild && hasMoney && withinLimit) {
        // 创建新塔
        gameState.towers.push(new Tower(x, y, gameState.selectedTowerType));
        gameState.gold -= config.towerCost[gameState.selectedTowerType];
        
        // 更新塔计数
        gameState.towerCounts[gameState.selectedTowerType]++;
        
        // 播放建造音效
        sounds.upgrade();
        
        // 显示建造成功提示
        createFloatingText(
          (x + 0.5) * config.tileSize,
          y * config.tileSize - 10,
          "建造成功!",
          "#00ff00"
        );
        
        // 不退出放置模式，允许继续建造
        if (!config.buildingSystem.mobileOptimized) {
          gameState.placementMode = false;
        }
        return;
      }
      
      // 提供明确的失败原因
      if (!canBuild) {
        if (gameState.map[y][x] === 1) {
          createFloatingText(
            touch.clientX,
            touch.clientY - 20,
            "不能建在路径上!",
            "#ff0000"
          );
        } else if (gameState.towers.some(tower => tower.x === x && tower.y === y)) {
          createFloatingText(
            touch.clientX,
            touch.clientY - 20,
            "此处已有塔!",
            "#ff0000"
          );
        }
      } else if (!hasMoney) {
        createFloatingText(
          touch.clientX,
          touch.clientY - 20,
          `金币不足! 需要${config.towerCost[gameState.selectedTowerType]}金币`,
          "#ff9900"
        );
      } else if (!withinLimit) {
        createFloatingText(
          touch.clientX,
          touch.clientY - 20,
          "已达到最大数量!",
          "#ff0000"
        );
      }
    }
  } catch (e) {
    console.error('处理触摸事件时出错:', e);
    createFloatingText(
      canvas.width / 2,
      canvas.height / 2,
      "操作出错，请重试",
      "#ff0000"
    );
  }
});

// 添加双击事件 - 用于退出放置模式
wx.onTouchEnd(function(e) {
  // 实现双击退出放置模式
  if (gameState.placementMode) {
    // 如果是双击，退出放置模式
    if (e.changedTouches.length > 0) {
      const touch = e.changedTouches[0];
      
      // 创建浮动文本显示当前状态
      createFloatingText(
        touch.clientX,
        touch.clientY - 20,
        "继续建造模式...",
        "#00ff00"
      );
    }
  }
});

// 优化触摸移动事件，减少抖动
let touchMoveThrottle = false;
wx.onTouchMove(function(e) {
  // 使用节流技术减少触发频率
  if (!touchMoveThrottle) {
    touchMoveThrottle = true;
    setTimeout(() => {
      touchMoveThrottle = false;
    }, 16); // 约60fps
    
    if (e.touches.length > 0) {
      const touch = e.touches[0];
      gameState.mouseX = touch.clientX;
      gameState.mouseY = touch.clientY;
    }
  }
});

// 初始化游戏
function init() {
  try {
    // 重置游戏状态
    gameState.towers = [];
    gameState.enemies = [];
    gameState.bullets = [];
    gameState.gold = config.startGold;
    gameState.wave = 1;
    gameState.lives = 10;
    gameState.score = 0;
    gameState.gameOver = false;
    gameState.selectedTowerType = 'basic';
    gameState.activeShields = [];
    gameState.lightningEffects = []; // 重置闪电特效
    gameState.towerCounts = {
      basic: 0,
      lightning: 0,
      sniper: 0,
      splash: 0,
      slow: 0,
      shield: 0
    };
    
    loadEnemyImages();  // 加载敌人图片资源
    initMap();
    initBuildSystem();  // 初始化建造系统
    
    // 自动进入建造模式
    if (config.buildingSystem.autoEnterBuildMode) {
      gameState.placementMode = true;
      gameState.selectedTowerType = 'basic'; // 默认选择基础塔
      
      // 添加提示文字
      setTimeout(() => {
        if (!gameState.showIntro) {
          createFloatingText(
            canvas.width / 2,
            canvas.height / 2 - 50,
            "点击绿色区域建造塔防! 绿色区域为可建造区域",
            "#00ff00"
          );
        }
      }, 500);
    }
    
    spawnWave();
    
    // 首次调用游戏循环，使用requestAnimationFrame
    requestAnimationFrame(gameLoop);
  } catch (e) {
    console.error('初始化游戏时出错:', e);
    // 显示错误
    ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = '#ff5555';
    ctx.font = '20px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('游戏初始化失败，请重新启动', canvas.width / 2, canvas.height / 2);
    ctx.fillText(e.message.substring(0, 30), canvas.width / 2, canvas.height / 2 + 30);
  }
}

// 启动游戏
init()